package com.sdhs.paas.sdk.base.common;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import com.sdhs.paas.sdk.base.page.Page;
/**
 * 
 * @ClassName: BaseDao
 * @Description: 基础Dao

 * @param <E>
 * @param <M>
 * @param <P>
 */

public abstract class BaseDao<E, M, P extends Serializable>  {
    protected static final Log LOG = LogFactory.getLog(BaseDao.class);
@Autowired
 private SqlSessionTemplate sqlSessionTemplate;

    public  SqlSessionTemplate getSqlSession(){

        return this.sqlSessionTemplate;
    }
    /**
     * 根据主键查询
     * 
     * @param primaryKey
     * @return
     */
    public E getById(P primaryKey) {
        E object = (E) sqlSessionTemplate.selectOne(
                getMapperNamespace() + ".getById", primaryKey);
        return object;
    }

    /**
     * 根据主键删除
     * 
     * @param primaryKey
     * @return
     */
    public int delete(P primaryKey) {
        int affectCount = getSqlSession().delete(
                getMapperNamespace() + ".deleteById", primaryKey);
        return affectCount;
    }

    /**
     * 根据实体删除 注意可能会造成批量删除
     * 
     * @param entity
     */
    public void delete(E entity) {
        getSqlSession().delete(getMapperNamespace() + ".delete", entity);
    }

    /**
     * 删除多条
     * 
     * @param ids
     */
    public void multiDelete(String ids) {
        getSqlSession().delete(getMapperNamespace() + ".multiDelete", ids);
    }

    /**
     * 查询distinct
     * 
     * @param 
     * @return
     */
    public List<E> getDistinct(E entity) {
        return getSqlSession().selectList(
                getMapperNamespace() + ".getDistinct", entity);
    }

    /**
     * 保存
     * 
     * @param entity
     * @return
     */
    public int save(E entity) {
        prepareObjectForSaveOrUpdate(entity);
        return getSqlSession().insert(getMapperNamespace() + ".insert", entity);
    }

    /**
     * 修改主键修改
     * 
     * @param entity
     */
    public int update(E entity) {
        prepareObjectForSaveOrUpdate(entity);
        int affectCount = getSqlSession().update(
                getMapperNamespace() + ".update", entity);
        return affectCount;
    }

    /**
     * 获取list
     * 
     * @param entity
     * @return
     */
    public List<E> getList(E entity) {
        List<E> list = getSqlSession().selectList(
                getMapperNamespace() + ".getList", entity);
        return list;
    }

    /**
     * 获取list数量
     * 
     * @param entity
     * @return
     */
    public int getListCount(E entity) {
        Number totalCount = (Number) getSqlSession().selectOne(
                getMapperNamespace() + ".getListCount", entity);
        return totalCount.intValue();
    }

    /**
     * 获取分页list
     * 
     * @param entity
     * @param bPos 开始位置
     * @param count 数量
     * @return
     */
    public List<E> getList(E entity, int bPos, int count) {
        RowBounds rowBounds = new RowBounds(bPos, count);
        List<E> list = getSqlSession().selectList(
                getMapperNamespace() + ".getList", entity, rowBounds);
        return list;
    }

    /**
     * 批量保存(外部循环)
     * 
     * @param list
     */
    public void saveBatch(List<E> list) {
        for (E entity : list) {
            prepareObjectForSaveOrUpdate(entity);
            getSqlSession().insert(getMapperNamespace() + ".insert", entity);
        }
    }

    /**
     * 批量保存(内部循环)
     * 
     * @param list
     */
    public void saveBatchInn(List<E> list) {
        getSqlSession().insert(getMapperNamespace() + ".insertBatch", list);
    }

    /**
     * 用于子类覆盖,在insert,update之前调用
     * 
     * @param 
     */
    protected void prepareObjectForSaveOrUpdate(E entity) {

    }

    /**
     * 获取Mapper
     * 
     * @param <M>
     * @param type
     * @return
     */
    public <M> M getMapperByType(Class<M> type) {
        return this.getSqlSession().getMapper(type);
    }

    /**
     * 获取Mapper命名空间 用于被子类覆盖
     * 
     * @return
     */
    public String getMapperNamespace() {
        throw new RuntimeException("not yet implement");
    }

    /**
     * rapid分页查询
     * 
     * @param statementName
     * @param countStatementName
     * @param pageRequest
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
	protected Page pageQuery(String statementName, String countStatementName,
                             BasePage<E> pageRequest) {
        Number totalCount = (Number) getSqlSession().selectOne(
                countStatementName, pageRequest.getFilters());

        if (totalCount == null || totalCount.longValue() <= 0) {
            return new Page(pageRequest, 0);
        }
        pageRequest.setPageSize(pageRequest.getCount());
        pageRequest.setPosStart(pageRequest.getPageSize()*(pageRequest.getPage()-1));
        List list = getSqlSession()
                .selectList(
                        statementName,
                        pageRequest.getFilters(),
                        new RowBounds(pageRequest.getPosStart(), pageRequest
                                .getCount()));

        Page page = new Page(pageRequest.getPageSize(), totalCount.intValue(), list);
        page.setResult(list);
        page.setCurPage(pageRequest.getPage());

        return page;
    }

    /**
     * 默认使用 语句+“Count” 作为查询数量语句
     * 
     * @param statementName
     * @param pageRequest
     * @return
     */
    public Page pageQuery(String statementName, BasePage pageRequest) {
        return pageQuery(getMapperNamespace() + "." + statementName,
                getMapperNamespace() + "." + statementName + "Count",
                pageRequest);
    }

    /**
     * 默认使用 getList + getListCount 作为查询数量语句
     * 
     * @param pageRequest
     * @return
     */
    public Page pageQuery(BasePage pageRequest) {
        return pageQuery(getMapperNamespace() + ".getList",
                getMapperNamespace() + ".getListCount", pageRequest);
    }

    public Page pageInventoryQuery(BasePage pageRequest) {
        return pageQuery(getMapperNamespace() + ".getInventoryList",
                getMapperNamespace() + ".getInventoryListCount", pageRequest);
    }

    public List findAll() {
        throw new UnsupportedOperationException();
    }

    public boolean isUnique(E entity, String uniquePropertyNames) {
        throw new UnsupportedOperationException();
    }

    public static interface SqlSessionCallback {
        public Object doInSession(SqlSession session);
    }

}
